/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package players;

import data.Line;
import interfaces.GameState;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author Marcel
 */
public class MyPlayer extends AbstractPlayer{

    
    private static final int INF = Integer.MAX_VALUE;
    private static int DEPTH = 4;
    private boolean isPlayer1 = false;
    
    @Override
    public Line makeMove(GameState gs) {
        //DEPTH++;
        return minimaxDecision(gs);
    }
    
    private Line max (Map<Integer, Line> l) {
        Integer m = new Integer(-INF);
        for (Map.Entry<Integer, Line> entry : l.entrySet())
        {
            m = Math.max(m,entry.getKey());
        }
        return l.get(m);
    }
    
    private Line min (Map<Integer, Line> l) {
        Integer m = new Integer(INF);
        for (Map.Entry<Integer, Line> entry : l.entrySet())
        {
            m = Math.min(m,entry.getKey());
        }
        return l.get(m);
    }
    
    
    
    private Line minimaxDecision(GameState state) {
        List<Line> lines = state.getRemainingLines();
        Map<Integer, Line> m = new HashMap<>();
        System.out.println("Início");
        int minMaxv = 0;
        int value = 0;
        this.isPlayer1 = (state.getPlayer() == 1);//lastMove() == null;
        if ( isPlayer1) System.out.println("macarena");
        for (Line line : lines) {
            GameState clone = state.clone();
            value = clone.addLine(line);
            if(value  == 0 ){
                minMaxv = minValue(DEPTH,clone);
            }else{
                minMaxv = maxValue(DEPTH,clone);
            }
            m.put(minMaxv,line);
            System.out.println(minMaxv+" ("+line.ax+","+line.ay+")("
                    +line.bx+","+line.by+")");
        }
        return max(m);
    }
    
    private int maxValue(int k, GameState state) {
        List<Line> lines = state.getRemainingLines();
        if(k == 0 || lines.isEmpty()){
            return state.getValue()*((this.isPlayer1)?1:-1);
        }
        int max = -INF, value = 0;
        for(Line line : lines){
            GameState clone = state.clone();
            value = clone.addLine(line);
            if(value < 1){
                max = Math.max(max, minValue(k-1, clone));
            }else{
                max = Math.max(max, maxValue(k-1, clone));
            }
        }
        return max;
    }
    
    private int minValue(int k,GameState state) {
        List<Line> lines = state.getRemainingLines();
        if(k == 0 || lines.isEmpty()){
            return state.getValue()*((this.isPlayer1)?1:-1);
        }
        int min = INF, value = 0;
        for(Line line : lines){
            GameState clone = state.clone();
            value = clone.addLine(line);
            if(value < 1){
                min = Math.min(min, maxValue(k-1, clone));
            }else{
                min = Math.min(min, minValue(k-1, clone));
            }
        }
        return min;
    }
    
//    function MINIMAX-DECISION(estado) retorna uma ação
//        return arg max a in ACTIONS ( s) MIN-VALUE(RESULT(state, a))
//    ______________________________________________________________
//    function MAX-VALUE( estado) retorna um valor de utilidade
//        if TERMINAL-TEST(estado) then return UTILITY(estado)
//            v = - 00
//        for each a in ACTIONS(estado) do
//            v <- MAX(v, MIN-VALUE(RESULT(s, a)))
//        return v
//    ______________________________________________________________
//    function MIN-VALUE( estado) retorna um valor de utilidade
//        if TERMINAL-TEST(estado) then return UTILITY(estado)
//            v = 00
//        for each a in ACTIONS(estado) do
//            v <- MIN(v, MAX-VALUE(RESULT(s, a)))
//        return v

    @Override
    public String getName() {
        return "Ultimate AI";
    }
    
}
